package com.transaction.manage.service;

import com.transaction.common.base.PageInfo;
import com.transaction.common.util.DateUtil;
import com.transaction.common.util.PageUtil;
import com.transaction.manage.localMapper.*;
import com.transaction.manage.model.dto.*;
import com.transaction.manage.model.vo.ComboboxVo;
import com.transaction.manage.model.vo.FundOpenDateVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
public class BusinessParamsService {

    @Autowired
    private FundInfoMapper fundInfoMapper;

    @Autowired
    private FundRelationMapper fundRelationMapper;

    @Autowired
    private FundYieldMapper fundYieldMapper;

    @Autowired
    private FundTransRateMapper fundTransRateMapper;

    @Autowired
    private ComboboxService comboboxService;

    @Autowired
    private TaService taService;

    @Autowired
    private FundOpenDateMapper fundOpenDateMappper;

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public List<FundInfo> selectFundInfoList(FundInfo fundInfo, PageInfo pageInfo) {
        PageUtil.StartPage(pageInfo);
        return fundInfoMapper.selectFundInfoList(fundInfo);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveFundInfo(FundInfo fundInfo) {

        Integer id = fundInfo.getId();
        String channelCode = fundInfo.getChannelCode();
        String fundCode = fundInfo.getFundCode();

        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode)) {
            throw new RuntimeException("渠道编码/产品编码不允许为空");
        }

        //日期转换格式
        exchangeFundInfoDate(fundInfo);
        //如果是新增
        if (id == null) {
            //判断该渠道产品是否已存在，存在，就直接修改,不存在，插入
            FundInfo oldFundInfo = fundInfoMapper.selectFundInfoByChannelAndFundCode(channelCode, fundCode);
            if(oldFundInfo != null){
                fundInfoMapper.updateFundInfoByChannelAndFundCode(fundInfo);
            }else{
                fundInfoMapper.insertFundInfo(fundInfo);
            }
        }else{
            //如果是修改
            FundInfo oldFundInfo = fundInfoMapper.selectFundInfoByChannelAndFundCode(channelCode, fundCode);
            if(oldFundInfo != null){//修改之后的渠道产品可以查出产品
                //如果查出的产品就是修改的这条
                if(id == oldFundInfo.getId()){
                    //根据id更新成最新的渠道和产品信息
                    fundInfoMapper.updateFundInfo(fundInfo);
                }else{
                    //抛出异常，存在相同渠道产品的产品存在
                    throw new RuntimeException("渠道:"+channelCode+",产品代码:"+fundCode+"的产品已存在,不允许修改成相同的产品");
                }
            }else{
                //根据id更新成最新的渠道和产品信息
                fundInfoMapper.updateFundInfo(fundInfo);
            }
        }
    }

    private void exchangeFundInfoDate(FundInfo fundInfo) {
        fundInfo.setIpoBeginDate(DateUtil.dateStrContainsTAndZToDateStr(fundInfo.getIpoBeginDate(),DateUtil.FORMAT_STR_TIME10));
        fundInfo.setIpoEndDate(DateUtil.dateStrContainsTAndZToDateStr(fundInfo.getIpoEndDate(),DateUtil.FORMAT_STR_TIME10));
        fundInfo.setSetUpDate(DateUtil.dateStrContainsTAndZToDateStr(fundInfo.getSetUpDate(),DateUtil.FORMAT_STR_TIME10));
        fundInfo.setMaturityDate(DateUtil.dateStrContainsTAndZToDateStr(fundInfo.getMaturityDate(),DateUtil.FORMAT_STR_TIME10));
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteFundInfo(String channelCode, String fundCode) {
        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode)) {
            throw new RuntimeException("渠道编码/产品编码不允许为空");
        }
        fundInfoMapper.deleteFundInfo(channelCode, fundCode);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void checkFundInfo(String channelCode, String fundCode) {
        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode)) {
            throw new RuntimeException("渠道编码/产品编码不允许为空");
        }
        fundInfoMapper.checkFundInfo(channelCode, fundCode);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public Map<String, Object> selectFundInfoModalAllCombobox() {
        Map<String, Object> map = new HashedMap<>();
        //代销渠道编码
        List<ComboboxVo> channelCodes = comboboxService.selectValidChannelInfoCombobox();
        //产品类型
        List<ComboboxVo> fundTypes = comboboxService.selectAllChildrenByDictKey("fundType");
        //支付类型
        List<ComboboxVo> payTypes = taService.getPayTypeCombobox();

        map.put("fundTypes", fundTypes);
        map.put("channelCodes", channelCodes);
        map.put("payTypes", payTypes);

        return map;
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public Map<String, Object> selectFundRelationModalAllCombobox() {
        Map<String, Object> map = new HashedMap<>();
        //代销渠道编码
        List<ComboboxVo> channelCodes = comboboxService.selectValidChannelInfoCombobox();
        //TA产品编码
        List<ComboboxVo> taFundCodes = taService.getFundCodeCombobox();
        //产品编码
        List<ComboboxVo> fundCodes = comboboxService.selectValidFundInfoCombobox(null);

        map.put("channelCodes", channelCodes);
        map.put("fundCodes", fundCodes);
        map.put("taFundCodes", taFundCodes);

        return map;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void checkFundRelation(String channelCode, String fundCode, String taFundCode) {
        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode) || StringUtils.isEmpty(taFundCode)) {
            throw new RuntimeException("渠道编码/产品编码/TA产品编码不允许为空");
        }
        fundRelationMapper.checkFundRelation(channelCode,fundCode,taFundCode);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteFundRelation(String channelCode, String fundCode, String taFundCode) {
        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode) || StringUtils.isEmpty(taFundCode)) {
            throw new RuntimeException("渠道编码/产品编码/TA产品编码不允许为空");
        }
        fundRelationMapper.deleteFundRelation(channelCode,fundCode,taFundCode);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveFundRelation(FundRelation fundRelation) {
        Integer id = fundRelation.getId();
        String channelCode = fundRelation.getChannelCode();
        String fundCode = fundRelation.getFundCode();
        String taFundCode = fundRelation.getTaFundCode();

        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode) || StringUtils.isEmpty(taFundCode)) {
            throw new RuntimeException("渠道编码/产品编码/TA产品编码不允许为空");
        }

        //如果是新增
        if (id == null) {
            //判断该渠道产品关系是否已存在，存在，就直接修改,不存在，插入
            FundRelation oldFundRelation = fundRelationMapper.selectFundRelationByChannelAndFundAndTaFundCode(channelCode, fundCode,taFundCode);
            if(oldFundRelation != null){
                fundRelationMapper.updateFundRelationByChannelAndFundAndTaFundCode(fundRelation);
            }else{
                fundRelationMapper.insertFundRelation(fundRelation);
            }
        }else{
            //如果是修改
            FundRelation oldFundRelation = fundRelationMapper.selectFundRelationByChannelAndFundAndTaFundCode(channelCode, fundCode,taFundCode);
            if(oldFundRelation != null){//修改之后的渠道产品可以查出产品
                //如果查出的产品就是修改的这条
                if(id == oldFundRelation.getId()){
                    //根据id更新成最新的渠道和产品信息
                    fundRelationMapper.updateFundRelation(fundRelation);
                }else{
                    //抛出异常，存在相同渠道产品的产品存在
                    throw new RuntimeException("渠道:"+channelCode+",产品代码:"+fundCode+",TA产品代码:"+taFundCode+"的关系已存在,不允许修改成相同的产品");
                }
            }else{
                //根据id更新成最新的渠道和产品信息
                fundRelationMapper.updateFundRelation(fundRelation);
            }
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public List<FundRelation> selectFundRelationList(FundRelation fundRelation, PageInfo pageInfo) {
        PageUtil.StartPage(pageInfo);
        return fundRelationMapper.selectFundRelationList(fundRelation);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public List<FundYield> selectFundYieldList(FundYield fundYield, PageInfo pageInfo) {
        PageUtil.StartPage(pageInfo);
        return fundYieldMapper.selectFundYieldList(fundYield);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveFundYield(FundYield fundYield) {
        Integer id = fundYield.getId();
        String channelCode = fundYield.getChannelCode();
        String fundCode = fundYield.getFundCode();
        BigDecimal beginAmount = fundYield.getBeginAmount();
        BigDecimal endAmount = fundYield.getEndAmount();

        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode)
                || beginAmount == null || endAmount == null) {
            throw new RuntimeException("渠道编码/产品编码/金额不允许为空");
        }

        //如果是新增
        if (id == null) {
            //判断该渠道产品金额范围的收益率是否存在，存在，就直接修改,不存在，插入
            FundYield oldFundYield = fundYieldMapper.selectFundYieldByChannelAndFundAndAmount(channelCode, fundCode,beginAmount,endAmount);
            if(oldFundYield != null){
                throw new RuntimeException("存在渠道:"+channelCode+",产品:"+fundCode+",起始金额:"+beginAmount+",截止金额:"+endAmount+",有交叉情况请检查！");
            }else{
                fundYieldMapper.insertFundYield(fundYield);
            }
        }else{
            //如果是修改
            FundYield oldFundYield = fundYieldMapper.selectFundYieldByChannelAndFundAndAmount(channelCode, fundCode,beginAmount,endAmount);
            if(oldFundYield != null){//修改之后的渠道产品可以查出产品
                //如果查出的产品就是修改的这条
                if(id == oldFundYield.getId()){
                    //根据id更新成最新的受益级别
                    fundYieldMapper.updateFundYield(fundYield);
                }else{
                    //抛出异常，存在相同渠道产品的产品存在
                    throw new RuntimeException("存在渠道:"+channelCode+",产品:"+fundCode+",起始金额:"+beginAmount+",截止金额:"+endAmount+",有交叉情况请检查！");
                }
            }else{
                //根据id更新成最新的受益级别
                fundYieldMapper.updateFundYield(fundYield);
            }
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteFundYield(Integer id) {
        fundYieldMapper.deleteFundYield(id);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void checkFundYield(Integer id) {
        fundYieldMapper.checkFundYield(id);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public Map<String, Object> selectFundYieldModalAllCombobox() {
        Map<String, Object> map = new HashedMap<>();
        //代销渠道编码
        List<ComboboxVo> channelCodes = comboboxService.selectValidChannelInfoCombobox();
        //产品编码
        List<ComboboxVo> fundCodes = comboboxService.selectValidFundInfoCombobox(null);
        //产品受益类别
        List<ComboboxVo> fundYieldTypes = taService.getFundYieldTypes(null,null);

        map.put("channelCodes", channelCodes);
        map.put("fundCodes", fundCodes);
        map.put("fundYieldTypes", fundYieldTypes);

        return map;
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public List<FundTransRate> selectFundTransRateList(FundTransRate fundTransRate, PageInfo pageInfo) {
        PageUtil.StartPage(pageInfo);
        return fundTransRateMapper.selectFundTransRateList(fundTransRate);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveFundTransRate(FundTransRate fundTransRate) {
        Integer id = fundTransRate.getId();
        String channelCode = fundTransRate.getChannelCode();
        String fundCode = fundTransRate.getFundCode();
        String businessCode = fundTransRate.getBusinessCode();
        String currency = fundTransRate.getCurrency();
        Integer indiOrInstFlag = fundTransRate.getIndiOrInstFlag();
        BigDecimal beginAmount = fundTransRate.getBeginAmount();
        BigDecimal endAmount = fundTransRate.getEndAmount();

        String errorMsg = "存在渠道:"+channelCode+",产品:"+fundCode+",业务编码:"+businessCode+",个人/机构:"+indiOrInstFlag +",币种:"+currency+",起始金额:"+beginAmount+",截止金额:"+endAmount+",有交叉情况请检查！";

        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(fundCode) ||
                StringUtils.isEmpty(businessCode) || StringUtils.isEmpty(currency)
                || beginAmount == null || endAmount == null) {
            throw new RuntimeException("渠道编码/产品编码/业务编码/币种/金额不允许为空");
        }

        //如果是新增
        if (id == null) {
            //判断该渠道产品,业务，币种，金额范围的交易费率是否存在，存在，提示,不存在，插入
            FundTransRate oldFundTransRate = fundTransRateMapper.selectFundTransRate(fundTransRate);
            if(oldFundTransRate != null){
                throw new RuntimeException(errorMsg);
            }else{
                fundTransRateMapper.insertFundTransRate(fundTransRate);
            }
        }else{
            //如果是修改
            FundTransRate oldFundTransRate = fundTransRateMapper.selectFundTransRate(fundTransRate);
            if(oldFundTransRate != null){//修改之后的渠道产品可以查出产品
                //如果查出的产品就是修改的这条
                if(id == oldFundTransRate.getId()){
                    //根据id更新成最新的交易费率
                    fundTransRateMapper.updateFundTransRate(fundTransRate);
                }else{
                    //抛出异常，存在相同渠道产品的产品交易费率存在
                    throw new RuntimeException(errorMsg);
                }
            }else{
                //根据id更新成最新的受益级别
                fundTransRateMapper.updateFundTransRate(fundTransRate);
            }
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteFundTransRate(Integer id) {
        fundTransRateMapper.deleteFundTransRate(id);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void checkFundTransRate(Integer id) {
        fundTransRateMapper.checkFundTransRate(id);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public Map<String, Object> selectFundTransRateModalAllCombobox() {
        Map<String, Object> map = new HashedMap<>();
        //代销渠道编码
        List<ComboboxVo> channelCodes = comboboxService.selectValidChannelInfoCombobox();
        //产品编码
        List<ComboboxVo> fundCodes = comboboxService.selectTransRateFundInfoCombobox(null);
        //产品交易类别
        List<ComboboxVo> businessCodes = comboboxService.selectAllChildrenByDictKey("businessCode");
        //产品交易类别
        List<ComboboxVo> currencys = comboboxService.selectAllChildrenByDictKey("currency");

        map.put("channelCodes", channelCodes);
        map.put("fundCodes", fundCodes);
        map.put("businessCodes", businessCodes);
        map.put("currencys", currencys);

        return map;

    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public List<FundOpenDate> selectFundOpenDates(FundOpenDate fundOpenDate) {
        return fundOpenDateMappper.selectFundOpenDates(fundOpenDate);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    public Map<String, Object> selectFundOpenDateAllCombobox() {
        Map<String, Object> map = new HashedMap<>();
        //代销渠道编码
        List<ComboboxVo> channelCodes = comboboxService.selectValidChannelInfoCombobox();
        //产品编码
        List<ComboboxVo> fundCodes = comboboxService.selectOpenFundInfoCombobox(null);
        //产品交易类别
        List<ComboboxVo> businessCodes = comboboxService.selectAllChildrenByDictKey("businessCode");

        map.put("channelCodes", channelCodes);
        map.put("fundCodes", fundCodes);
        map.put("businessCodes", businessCodes);

        return map;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveFundOpenDates(FundOpenDateVo fundOpenDateVo) {
        List<FundOpenDate> fundOpenDates = fundOpenDateVo.getFundOpenDates();
        String channelCode = fundOpenDateVo.getChannelCode();
        String fundCode = fundOpenDateVo.getFundCode();
        String businessCode = fundOpenDateVo.getBusinessCode();
        String year = fundOpenDateVo.getYear();

        if (StringUtils.isEmpty(channelCode) || StringUtils.isEmpty(year) ||
                StringUtils.isEmpty(fundCode) || StringUtils.isEmpty(businessCode)) {
            throw new RuntimeException("渠道/产品/业务编码/年份不允许为空");
        }

        //1.删除该产品已存在保存年份的交易日
        fundOpenDateMappper.deleteFundOpenDate(fundOpenDateVo);

        if(CollectionUtils.isNotEmpty(fundOpenDates)) {
            //2.保存该产品选择的年份交易日
            fundOpenDateMappper.insertFundOpenDates(fundOpenDateVo);
        }
    }
}
